home *** CD-ROM | disk | FTP | other *** search
-
- /*
- * CPP.C
- *
- * (c)Copyright 1992 Obvious Implementations Corp, All Rights Reserved
- * CONFIDENTIAL, This is unpublished proprietary source code owned by Obvious Implementations Corp.
- * This material contains trade secrets of Obvious Implementations Corp.
- *
- */
-
- #include "defs.h"
-
- Prototype Include *PushBase;
- Prototype char WhiteSpace[256];
- Prototype char SpecialChar[256];
- Prototype char SymbolChar[256];
-
- Prototype void InitCpp(void);
- Prototype long cpp(long, int, char *, FILE *, char *, long);
- Prototype long SkipCommentLine(ubyte *, long, long);
- Prototype long SkipComment(ubyte *, long, long);
- Prototype long ExtSymbol(ubyte *, long, long);
- Prototype long SkipString(char *, long, long);
- Prototype long SkipSingleSpec(char *, long, long);
- Prototype void Dump(char *, long, long);
- Prototype void DoLineSpec(void);
-
- Include *PushBase;
- char WhiteSpace[256];
- char SpecialChar[256];
- char SymbolChar[256];
-
- void
- InitCpp()
- {
- short i;
-
- WhiteSpace[9] = 1;
- WhiteSpace[' '] = 1;
- WhiteSpace['\r'] = 1;
- WhiteSpace['l'&31] = 1;
-
- for (i = '0'; i <= '9'; ++i)
- SymbolChar[i] = 1;
- for (i = 'a'; i <= 'z'; ++i)
- SymbolChar[i] = 1;
- for (i = 'A'; i <= 'Z'; ++i)
- SymbolChar[i] = 1;
- SymbolChar['_'] = 1;
- SymbolChar[1] = 1; /* special for macro replace */
-
- SpecialChar['\''] = 1;
- SpecialChar['\"'] = 1;
- SpecialChar['/'] = 1;
- SpecialChar['?'] = 1;
- }
-
- long
- cpp(oldi, level, file, fi, xbuf, xbytes)
- long oldi;
- int level;
- char *file;
- FILE *fi;
- char *xbuf;
- long xbytes;
- {
- long len;
- long i;
- long w;
- short ifIndex = IfIndex;
- ubyte *base;
- Include inc;
-
- if (level >= MAX_INCLUDE_LEVEL)
- cerror(EFATAL_MAX_INCLUDE, level);
-
- if (fi == NULL && xbuf == NULL) {
- ErrorOpenFailed(file, 0);
- return(oldi);
- }
- if (fi) {
- fprintf(Fo, "# 1 \"%s\" %d\n", file, level);
- fseek(fi, 0L, 2);
- len = ftell(fi);
- if (len < 0) {
- cerror(EERROR_FILE_SIZE, file, len);
- fclose(fi);
- return(oldi);
- }
- base = malloc(len+1);
- if (base == NULL)
- ErrorNoMemory();
- fseek(fi, 0L, 0);
- {
- int n;
-
- if ((n = fread(base, 1, len, fi)) != len) {
- cerror(EERROR_READ_ERROR, file);
- fclose(fi);
- return(oldi);
- }
- }
- fclose(fi); /* fi no longer valid */
-
- base[len] = 0; /* emergency terminator to prevent bad code from crashing us! */
-
- /*
- * Check for tri-graphs, modify accordingly
- */
-
- if (TriGraph) {
- #ifdef NO_ASM
- char *ptr = base;
- char c;
-
- while (c = *ptr) {
- ++ptr;
- if (c == '?' && *ptr == '?') {
- if (c = TriGraphConvert(ptr[1])) {
- ptr[-1] = c;
- len -= 2;
- movmem(ptr + 2, ptr, len - (ptr - (char *)base));
- }
- }
- }
- #else
- len = HandleTriGraphs(base) - base;
- #endif
- }
- } else { /* else macro */
- base = xbuf;
- len = xbytes;
- }
- dbprintf(("CPP %s (%ld)\n", file, len));
-
- if (PushBase)
- PushBase->Index = oldi;
-
- inc.Next = PushBase;
- inc.FileName = file;
- inc.LineNo = 1;
- inc.Level = level;
- inc.IsFile = (fi) ? 1 : 0;
- inc.MaxIndex = len;
- inc.Base = base;
- PushBase = &inc;
-
- {
- int nl = 1; /* newline just occured */
- short c;
- short stringtize = 0;
-
- for (i = w = 0; i < len; ) {
- c = base[i];
-
- if (WhiteSpace[c]) { /* ignore white space */
- ++i;
- continue;
- }
- if (c == '\n') { /* newline */
- /*
- * handle line concat. XXX handle escape sequences? ANSI?
- */
- if (w < i && base[i-1] == '\\') {
- Dump(base, w, i - 1);
- w = i + 1;
- ForceLineSpec = 1;
- } else {
- if (ForceLineSpec) {
- Dump(base, w, i);
- w = i;
- DoLineSpec();
- }
- }
- ++inc.LineNo;
- nl = 1;
- ++i;
- continue;
- }
- if (c == '#') { /* directive, token pasting */
- if (nl && fi) {
- dbprintf(("directive\n"));
- Dump(base, w, i);
- /* execute directive */
- w = i = HandleDirective(base, i + 1, len);
- continue;
- } else if (base[i+1] == '#') {
- long si = i + 2;
- while (i >= w && WhiteSpace[base[--i]]);
- ++i;
- Dump(base, w, i);
- i = si;
- while (i < len && WhiteSpace[base[i]])
- ++i;
- w = i;
- continue;
- } else if (fi == NULL) {
- Dump(base, w, i);
- stringtize = 1;
- w = ++i;
- continue;
- }
- }
- nl = 0; /* NOT a directive */
-
- /*
- * Do not misinterpret a number as a symbol, especially parts
- * of the number that contain characters such as 0x23 or
- * 0.234E+4 It will suffice to include '.' in our definition
- * of a symbol for this loop
- *
- * Note that embedded characters in numbers will not be handled
- * by DC1 if symbolized for precompiled includes, but the
- * processing of this is handled in PRECOMP.C, not here.
- */
-
- if (c >= '0' && c <= '9') {
- for (++i; i < len && (SymbolChar[c = base[i]] || c == '.'); ++i)
- ;
- continue;
- }
-
- /*
- * symbol?
- */
-
- if (IfEnabled && SymbolChar[c]) {
- long b = i;
- Sym *node;
-
- i = ExtSymbol(base, i, len); /* extract symbol */
- if (node = FindSymbol(base + b, i - b)) {
- if (node->Type && SF_MACROARG && stringtize)
- node->Type |= SF_STRINGIZE;
- Dump(base, w, b);
- w = i = HandleSymbol(node, base, i, len);
- node->Type &= ~SF_STRINGIZE;
- } else if (PreCompFlag) {
- short t;
-
- /*
- * Precomp optimization
- */
-
- if (t = PreCompSymbol(base + b, i - b)) {
- Dump(base, w, b);
- w = i;
- putc(((char *)&t)[0], Fo);
- putc(((char *)&t)[1], Fo);
- }
- }
- stringtize = 0;
- continue;
- } /* delete comments */
- if (stringtize)
- cerror(EERROR_STRINGTIZE);
-
- if (SpecialChar[c]) {
- if (c == '\'') {
- i = SkipSingleSpec(base, i + 1, len);
- continue;
- }
- if (c == '\"') {
- i = SkipString(base, i + 1, len);
- continue;
- }
- if (c == '/') {
- if (base[i+1] == '*') {
- Dump(base, w, i);
- w = i = SkipComment(base, i + 2, len);
- putc(' ', Fo);
- continue;
- }
- if (base[i+1] == '/' && SlashSlashOpt) {
- Dump(base, w, i);
- w = i = SkipCommentLine(base, i + 2, len);
- continue;
- }
- }
- }
- ++i;
- }
- Dump(base, w, i);
- /* w = i */
- }
-
- if (xbuf == NULL)
- free(base);
-
- if (IfIndex != ifIndex)
- cerror(EWARN_IFS_LEFT_PENDING, IfIndex, ifIndex);
-
- PushBase = inc.Next;
-
- if (PushBase) {
- if (fi)
- DoLineSpec();
- return(PushBase->Index);
- }
- return(0);
- }
-
- long
- SkipCommentLine(base, i, max)
- ubyte *base;
- long i;
- long max;
- {
- while (i < max && base[i] != '\n')
- ++i;
- if (i == max)
- cerror(EERROR_UNEXPECTED_EOF);
- return(i);
- }
-
- long
- SkipComment(base, i, max)
- ubyte *base;
- long i;
- long max;
- {
- char c;
-
- while (i < max) {
- c = base[i];
- if (c == '/' && base[i+1] == '*')
- cerror(EWARN_NESTED_COMMENT);
- if (c == '*' && base[i+1] == '/')
- break;
- if (c == '\n') {
- ++PushBase->LineNo;
- putc('\n', Fo);
- }
- ++i;
- }
- if (i == max) {
- cerror(EERROR_UNEXPECTED_EOF);
- } else {
- i += 2;
- if (i > max)
- cerror(EFATAL_SOFTERROR_177);
- }
- return(i);
- }
-
- long
- ExtSymbol(base, i, max)
- ubyte *base;
- long i;
- long max;
- {
- long b = i;
- char *sc = SymbolChar;
-
- while (i < max && sc[base[i]])
- ++i;
-
- dbprintf(("ExtSymbol: %.*s\n", i - b, base + b));
-
- return(i);
- }
-
- #ifdef NOTDEF
-
- /*
- * This routine strips comments from a buffer
- */
-
- void
- StripComments(buf, bytes)
- char *buf;
- long bytes;
- {
- char c;
- long i;
- long b;
-
- for (i = 0; i < bytes; ++i) {
- if (buf[i] == '/' && i + 1 < bytes) {
- if (buf[i+1] == '*') {
- b = i;
- i += 2;
- while (i < bytes) {
- if (buf[i] == '*' && buf[i+1] == '/' && i + 1 < bytes) {
- i += 2;
- break;
- }
- ++i;
- }
- setmem(buf + b, i - b, ' ');
- } else if (buf[i+1] == '/' && SlashSlashOpt) {
- b = i;
- while (i < bytes && buf[i] != '\n')
- ++i;
- setmem(buf + b, i - b, ' ');
- --i;
- }
- }
- }
- }
-
- #endif
-
- long
- SkipString(char *base, long i, long max)
- {
- while (i < max && base[i] != '\"') {
- /*
- * Embedded newline with no previous backslash
- */
-
- if (base[i] == '\n') {
- cerror(EERROR_UNTERMINATED_STRING);
- break;
- }
-
- /*
- * Leave backslashes alone. The specical case of a \ followed
- * by a newline is handled by DC1
- */
-
- if (base[i] == '\\') {
- ++i;
- }
- ++i;
- }
- if (i < max)
- ++i;
- return(i);
- }
-
- long
- SkipSingleSpec(char *base, long i, long max)
- {
- while (i < max && base[i] != '\'') {
- if (base[i] == '\n') {
- cerror(EERROR_UNTERMINATED_CHARCONST);
- break;
- }
- if (base[i] == '\\')
- ++i;
- ++i;
- }
- if (i < max)
- ++i;
- return(i);
- }
-
- void
- Dump(base, w, i)
- char *base;
- long w;
- long i;
- {
- if (w < i) {
- if (IfEnabled) {
- if (GlobalStringize) {
- long n;
- for (n = w; n < i; ++n) {
- char c = base[n];
- if (c < 32 || c == '\"' || c == '\'' /* || c == '\\'*/) {
- fprintf(Fo, "\\%03o", (ubyte)c);
- } else {
- putc(c, Fo);
- }
- }
- } else {
- fwrite(base + w, 1, i - w, Fo);
- }
- } else {
- while (w < i) {
- if (base[w] == '\n')
- fputc('\n', Fo);
- ++w;
- }
- }
- }
- }
-
- void
- DoLineSpec()
- {
- fprintf(Fo, "\n# %d \"%s\" %d\n", PushBase->LineNo, PushBase->FileName, PushBase->Level);
- ForceLineSpec = 0;
- }
-
-